package com.example.imtoken.core.logic.network

import com.blankj.utilcode.util.LogUtils
import com.example.imtoken.core.App
import com.example.imtoken.core.logic.network.api.ApiService
import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.RequestBody
import okhttp3.Response
import okio.Buffer
import okio.IOException
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.nio.charset.Charset
import java.util.concurrent.TimeUnit

object RetrofitUtils {

    private const val URL = "http://116.211.17.68:8585/api/"

    private const val URL2 = "http://27.124.6.52:28080/api/"

    private const val CONNECT_TIME = 60
    private const val WRITE_TIME = 60
    private const val READ_TIME = 60
    var apiService: ApiService? = null
        get() {
            if (field == null) {
                synchronized(RetrofitUtils::class.java) {
                    if (field == null) {
                        field = retrofit.create(ApiService::class.java)
                    }
                }
            }
            return field
        }
    private val retrofit: Retrofit
        get() = Retrofit.Builder()
            .baseUrl(URL)
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .addConverterFactory(GsonConverterFactory.create())
            .client(okHttpClient)
            .build()

    private val okHttpClient: OkHttpClient
        get() = OkHttpClient.Builder()
            .connectTimeout(CONNECT_TIME.toLong(), TimeUnit.SECONDS)
            .writeTimeout(WRITE_TIME.toLong(), TimeUnit.SECONDS)
            .readTimeout(READ_TIME.toLong(), TimeUnit.SECONDS)
            .addInterceptor {
                val requestBuilder = it.request().newBuilder()
                App.createLiveData.value?.let { e ->
                    e.token?.let { token ->
                        requestBuilder.addHeader("Authorization", token)
                    }
                }
                val request = requestBuilder.build()
                return@addInterceptor it.proceed(request)
            }
            .addInterceptor(BaseUrlInterceptor())
            .addInterceptor(LoggingInterceptor())
//            .addInterceptor(Objects.requireNonNull(interceptor))
            .build()

    private fun printParams(body: RequestBody?): String? {
        val buffer = Buffer()
        try {
            body?.writeTo(buffer)
            var charset = Charset.forName("UTF-8")
            val contentType = body?.contentType()
            if (contentType != null) {
                charset = contentType.charset(Charset.defaultCharset())
            }
            return buffer.readString(charset)
        } catch (e: IOException) {
            e.printStackTrace()
        }
        return null
    }

    class BaseUrlInterceptor : Interceptor {
        override fun intercept(chain: Interceptor.Chain): Response {
            val request = chain.request()
            val headerValues = request.headers("urlName")
            if (headerValues.isNotEmpty()) {
                val headerValue = headerValues[0]
                val newBaseUrl = if (headerValue == "url2") {
                    URL2.toHttpUrlOrNull()
                } else {
                    null
                }
                if (newBaseUrl != null) {
                    val newHttpUrl = request.url.newBuilder()
                        .host(newBaseUrl.host)
                        .port(newBaseUrl.port)
                        .build()
                    val newRequest = request.newBuilder().url(newHttpUrl).build()
                    return chain.proceed(newRequest)
                }
            }
            return chain.proceed(request)
        }

    }

    class LoggingInterceptor : Interceptor {

        @Throws(java.io.IOException::class)
        override fun intercept(chain: Interceptor.Chain): Response {
            val UTF8 = Charset.forName("UTF-8")

            val request = chain.request()
            val requestBody = request.body
            var reqBody = ""
            if (requestBody != null) {
                val buffer = Buffer()
                requestBody.writeTo(buffer)
                var charset: Charset? = null
                val contentType = requestBody.contentType()
                if (contentType != null) {
                    charset = contentType.charset(UTF8)
                }
                if (charset != null) reqBody = buffer.readString(charset)
            }

            val t1 = System.nanoTime()

            LogUtils.e(
                "发送请求",
                "请求地址:${request.url}",
                "请求头部:${request.headers}",
                "请求参数:$reqBody"
            )
            // "Sending request: ${request.url} \n ${request.headers} \n $reqBody"

            val response = chain.proceed(request)

            val t2 = System.nanoTime()
            LogUtils.e(
                TAG,
                "Received response for  ${
                    response.request.url
                } in ${(t2 - t1) / 1e6} ms\n${response.headers}"
            )
            return response
        }

        companion object {
            const val TAG = "LoggingInterceptor"
        }
    }

//    private val interceptor = Interceptor { chain ->
//        val original = chain.request()
//        val startTime = TimeUtils.getNowString()
//        val startMillis = System.currentTimeMillis()
//        val response = chain.proceed(chain.request())
//        val endTime = TimeUtils.getNowString()
//        val endMillis = System.currentTimeMillis()
//        val duration = endMillis - startMillis
//        val content = response.body?.string()
//        val params = printParams(original.body)
//        LogUtils.i(
//            "---------- 接口请求信息 ----------",
//            "---> 请求开始时间: $startTime",
//            "---> 接口地址: $original",
//            "---> 请求参数: $params",
//            "---> 请求结束时间: $endTime",
//            "---> 请求耗时: $duration 毫秒"
//        )
//        LogUtils.json("请求的Json结果,$duration", content)
//
//        response
//    }
}